package com.qboot.generate.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.io.FileUtil;
import cn.smallbun.screw.core.Configuration;
import cn.smallbun.screw.core.engine.EngineConfig;
import cn.smallbun.screw.core.engine.EngineFileType;
import cn.smallbun.screw.core.engine.EngineTemplateType;
import cn.smallbun.screw.core.execute.DocumentationExecute;
import com.qboot.common.consts.CommonConst;
import com.qboot.common.exception.BusinessException;
import com.qboot.common.utils.SpringUtils;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.compress.utils.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;

/**
 * 数据库文档
 *
 * @author Tellsea
 * @date 2023/1/30
 */
@Api(tags = "数据库文档 控制层")
@RestController
@RequestMapping("/generate/dataBaseDoc")
public class DataBaseDocController {

    @Value("${spring.datasource.driverClassName}")
    private String driverClassName;
    @Value("${spring.datasource.druid.url}")
    private String url;
    @Value("${spring.datasource.druid.username}")
    private String username;
    @Value("${spring.datasource.druid.password}")
    private String password;

    @ApiOperation("数据库文档-预览")
    @SaCheckPermission("generate:dataBaseDoc:preview")
    @GetMapping("/preview")
    public String preview() {
        generateFile(EngineFileType.HTML);
        return FileUtil.readUtf8String(CommonConst.TEMP_PATH + "/database.html");
    }

    @ApiOperation("数据库文档-下载")
    @SaCheckPermission("generate:dataBaseDoc:download")
    @GetMapping("/download")
    public void download(@RequestParam("type") String type) {
        String fileType;
        if (StringUtils.equals(type, "html")) {
            generateFile(EngineFileType.HTML);
            fileType = ".html";
        } else if (StringUtils.equals(type, "doc")) {
            generateFile(EngineFileType.WORD);
            fileType = ".doc";
        } else if (StringUtils.equals(type, "md")) {
            generateFile(EngineFileType.MD);
            fileType = ".md";
        } else {
            throw new BusinessException("文档类型不匹配");
        }
        try {
            HttpServletResponse response = SpringUtils.getResponse();
            FileInputStream fis = new FileInputStream(new File(CommonConst.TEMP_PATH, "database" + fileType));
            response.setHeader("content-disposition", "attachment;fileName=" + URLEncoder.encode("database" + fileType, "UTF-8"));
            ServletOutputStream os = response.getOutputStream();
            IOUtils.copy(fis, os);
            fis.close();
            os.close();
        } catch (IOException e) {
            throw new BusinessException("下载文件异常");
        }
    }

    /**
     * 生成数据库文档文件
     *
     * @param engineFileType
     */
    private void generateFile(EngineFileType engineFileType) {
        HikariConfig hikariConfig = new HikariConfig();
        hikariConfig.setDriverClassName(driverClassName);
        hikariConfig.setJdbcUrl(url);
        hikariConfig.setUsername(username);
        hikariConfig.setPassword(password);
        hikariConfig.addDataSourceProperty("useInformationSchema", "true");
        hikariConfig.setMinimumIdle(2);
        hikariConfig.setMaximumPoolSize(5);
        DataSource dataSource = new HikariDataSource(hikariConfig);
        EngineConfig engineConfig = EngineConfig.builder()
                .fileOutputDir(CommonConst.TEMP_PATH)
                .fileType(engineFileType)
                .produceType(EngineTemplateType.freemarker)
                .fileName("database")
                .build();
        Configuration config = Configuration.builder()
                .version("1.0.0")
                .dataSource(dataSource)
                .engineConfig(engineConfig)
                .description("数据库文档")
                .build();
        new DocumentationExecute(config).execute();
    }
}
